﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SGS.Logics.Core
{
    public class GameTimeEventArgs : EventArgs
    {
        public GameTimeEventArgs(GameTime gameTime)
        {
            this.GameTime = gameTime;
        }
        public GameTime GameTime { set; get; }
    }

    public class MachineState : HierarchyStateMachine
    {
        private bool TimerEnabled
        {
            get;
            set;
        }

        public float ElapsedTime
        {
            get;
            set;
        }

        public float ExpectedTime
        {
            get;
            set;
        }

        public MachineState NextState
        {
            get;
            set;
        }

        public bool InTime(float start = -1.0f, float end = -1.0f)
        {
            bool left = (start < 0) || (start >= -0.01f && start <= this.ElapsedTime);
            bool right = (end < 0) || (end >= -0.01f && this.ElapsedTime <= end);
            return left && right;
        }

        public event EventHandler<GameTimeEventArgs> StartEvent;

        public event EventHandler<GameTimeEventArgs> UpdateEvent;

        public event EventHandler<GameTimeEventArgs> TerminateEvent;

        public string FullStateName
        {
            get
            {
                if (this.Owner == null)
                    return this.StateName;
                else
                {
                    MachineState state = this.Owner as MachineState;
                    if (state != null)
                        return state.FullStateName + " " + this.StateName;
                    else
                        return this.StateName;
                }
            }
        }

        public string StateName
        {
            get;
            set;
        }

        public HierarchyStateMachine Owner
        {
            get;
            set;
        }

        public MachineState()
        {
            this.Initialize();
        }

        public MachineState(HierarchyStateMachine owner, string stateName)
        {
            this.Owner = owner;
            this.StateName = stateName;

            this.Initialize();
        }

        public virtual void Initialize()
        {
        }

        public void EnableInternalTimer(float expectedTime, MachineState nextState)
        {
            this.TimerEnabled = true;
            this.ElapsedTime = 0;
            this.ExpectedTime = expectedTime;
            this.NextState = nextState;
        }

        private void Reset()
        {
            ElapsedTime = ExpectedTime = 0;
            NextState = null;
            TimerEnabled = false;
        }

        public void Start(GameTime gameTime)
        {
            if (StartEvent != null)
                StartEvent(this, new GameTimeEventArgs(gameTime));
            ElapsedTime = 0;
        }

        public override void Update(GameTime gameTime)
        {
            ElapsedTime += (float)gameTime.ElapsedTime.TotalSeconds;
            if (ElapsedTime > ExpectedTime && TimerEnabled == true)
            {
                if (NextState != null)
                    this.Owner.ChangeToState(NextState.StateName);
                return;
            }

            if (UpdateEvent != null)
            {
                //if (this.ChildrenStateCount == 0)
                //    Helper.LogState(this.FullStateName);
                UpdateEvent(this, new GameTimeEventArgs(gameTime));
            }

            base.Update(gameTime);
        }

        public void Terminate(GameTime gameTime)
        {
            if (TerminateEvent != null)
                TerminateEvent(this, new GameTimeEventArgs(gameTime));
        }
    }
}
